/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controller;

import ControllerInterface.*;
import ModelInterface.*;
import ViewInterface.AbstractViewMapFactory;
import ViewInterface.IViewMain;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

/**
 *
 * @author Fabian
 */
public class ControllerMainMapping implements IControllerMainMapping {

    private IControllerSchemaMapping mappingSchema;
    private IControllerCrawler crawlerControler;
    private IControllerDataMap dataMapControler;
    private IViewMain vistaPrincipal;
    private IModelMainMapping modeloMap;
    private IEventMap evento;
    private IPlaceHasCommunity myPlaceHasCom;
    private IPlaceHasItem myPlaceHasItem;
    private ICommunityHasUser myComHasUser;
    /**
     * 
     */
    public DatabaseMetaData metadatosS;
    /**
     * 
     */
    public DatabaseMetaData metadatosT;
    /**
     * 
     */
    public DefaultTreeModel sourceModel;
    /**
     * 
     */
    public DefaultTreeModel targetModel;
    private String pathS;
    private String pathT;
    private String dbNameS;
    private String dbNameT;
    private String userS;
    private String userT;
    private String passS;
    private String passT;
    private int typeS;
    private int typeT;
    private boolean crawMode;
    private boolean dataMode;

    /**
     * 
     */
    public ControllerMainMapping() {
        /*
         * Controlador de esquemas
         */
        this.mappingSchema = AbstractControllerMapFactory.getAbstractControllerFactory().getControllerSchemaMapping();
        
        /* Controlador de crawling*/
        this.crawlerControler = AbstractControllerMapFactory.getAbstractControllerFactory().getControllerCrawler();
        
        /* Controlador de dataMap*/
        this.dataMapControler = AbstractControllerMapFactory.getAbstractControllerFactory().getControllerDataMap();
        
        /*
         * Vista principal
         */
        this.vistaPrincipal = AbstractViewMapFactory.getAbstractViewMapFactory().getVistaPrincipal();
        this.vistaPrincipal.setController(this);
        this.vistaPrincipal.setVisibleViewMain(true);

        /*
         * Modelo para conexion
         */
        this.modeloMap = AbstractModelMapFactory.getAbstractModelMapFactory().getMainModel();
        this.evento = AbstractModelMapFactory.getAbstractModelMapFactory().getEvent();
        this.myPlaceHasCom = AbstractModelMapFactory.getAbstractModelMapFactory().getIPlaceHasCommunity();
        this.myPlaceHasItem = AbstractModelMapFactory.getAbstractModelMapFactory().getIPlaceHasItem();
        this.myComHasUser = AbstractModelMapFactory.getAbstractModelMapFactory().getICommunityHasUser();

    }

     private DefaultTreeModel setModelTree(DatabaseMetaData metadatos, String nameBD) throws SQLException {

        ResultSet rsTables = metadatos.getTables(null, null, "%", null);                  //carga el esquema de las tablas de la BD
        String catalogo;
        String tabla;
        String nombreColumna;
        String tipoColumna;
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(nameBD);                 //crea el nodo raiz del arbol, con el nombre de la BD

        while (rsTables.next()) {
            catalogo = rsTables.getString(1);
            tabla = rsTables.getString(3);
//            System.out.println("TABLA=" + catalogo + "." + tabla);
            DefaultMutableTreeNode table = new DefaultMutableTreeNode(tabla);
            if (!table.toString().equals("typeevent")) {
                ResultSet rsColumns = metadatos.getColumns(catalogo, null, tabla, null);      //se obtienen todas las columnas de la tabla "tabla"
                while (rsColumns.next()) {
                    nombreColumna = rsColumns.getString(4);                                   //se rescata el nombre de la columna
                    tipoColumna = rsColumns.getString(6);                                     //se rescata el tipo de la columna
//                System.out.println(" COLUMNA, nombre=" + nombreColumna
//                        + " tipo = " + tipoColumna);

                    DefaultMutableTreeNode column = new DefaultMutableTreeNode(nombreColumna + " (" + tipoColumna + ")");
                    table.add(column);
                }
            }
            if (!table.toString().equals("value")) {
                root.add(table);
            }
        }
        return new DefaultTreeModel(root);
    }
    
     /**
      * 
      * @param _pathS
      * @param _dbNameS
      * @param _userS
      * @param _passS
      * @param _typeS
      * @return
      */
     @Override
    public boolean setInfoDBSource(String _pathS, String _dbNameS, String _userS, String _passS, int _typeS) {
        this.pathS = _pathS;
        this.dbNameS = _dbNameS;
        this.userS = _userS;
        this.passS = _passS;
        this.typeS = _typeS;

        if (modeloMap.setDBConnectionSource(pathS, dbNameS, userS, passS, typeS)) {
            metadatosS = modeloMap.getModelDBs();
            try {
                this.sourceModel = setModelTree(metadatosS,"Origen");
            } catch (SQLException ex) {
                Logger.getLogger(ControllerMainMapping.class.getName()).log(Level.SEVERE, null, ex);
            }
            this.evento.setDAOSourceConnection(modeloMap.getDBConnectionSource());
            this.myPlaceHasCom.setDAOSourceConnection(modeloMap.getDBConnectionSource());
            this.myPlaceHasItem.setDAOSourceConnection(modeloMap.getDBConnectionSource());
            this.myComHasUser.setDAOSourceConnection(modeloMap.getDBConnectionSource());
            return true;
        }

        return false;

    }

    /**
     * 
     * @param _pathT
     * @param _dbNameT
     * @param _userT
     * @param _passT
     * @param _typeT
     * @return
     */
    @Override
    public boolean setInfoDBTarget(String _pathT, String _dbNameT, String _userT, String _passT, int _typeT) {
        this.pathT = _pathT;
        this.dbNameT = _dbNameT;
        this.userT = _userT;
        this.passT = _passT;
        this.typeT = _typeT;
   
        if (modeloMap.setDBConnectionTarget(pathT, dbNameT, userT, passT, typeT)) {
            metadatosT = modeloMap.getModelDBt();
            try {
                this.targetModel = setModelTree(metadatosT,"Destino");
            } catch (SQLException ex) {
                Logger.getLogger(ControllerMainMapping.class.getName()).log(Level.SEVERE, null, ex);
            }
            this.evento.setDAOTargetConnection(modeloMap.getDBConnectionTarget());
            this.myPlaceHasCom.setDAOTargetConnection(modeloMap.getDBConnectionTarget());
            this.myPlaceHasItem.setDAOTargetConnection(modeloMap.getDBConnectionTarget());
            this.myComHasUser.setDAOTargetConnection(modeloMap.getDBConnectionTarget());
            if(dataMode){
                this.dataMapControler.setController(this);
                this.dataMapControler.startDataMap();  
                dataMode = false;
            }else if(crawMode){
                this.crawlerControler.setController(this);
                this.crawlerControler.startCrawlerMode();
                crawMode = false;
            }else{
                this.mappingSchema.setMainModel(modeloMap);
                this.mappingSchema.setModelMap(sourceModel, targetModel);
                this.mappingSchema.set3OntologyModel(evento, myPlaceHasCom, myPlaceHasItem, myComHasUser);
                this.mappingSchema.startMappingMode();
            }
            return true;
        }

        return false;
    }

    /**
     * 
     * @return
     */
    @Override
    public boolean setCrawlerMode() {
        crawMode = true;
        return true;
    }
    
    /**
     * 
     * @return
     */
    @Override
    public boolean setDataMode() {
        dataMode = true;
        return true;
    }

    /**
     * 
     * @param modeloCrawler
     * @param _metaS
     */
    @Override
    public void mapFromCrawler(IModelCrawler modeloCrawler, DefaultTreeModel _metaS) {
        sourceModel = _metaS;
        this.mappingSchema.setMainModel(modeloCrawler);
        this.mappingSchema.setModelMap(sourceModel, targetModel);
        this.mappingSchema.set3OntologyModel(evento, myPlaceHasCom, myPlaceHasItem, myComHasUser);
        this.mappingSchema.startMappingMode();
    }
    
    /**
     * 
     * @param modeloDataMap
     * @param _metaS
     * @param separador
     */
    @Override
    public void mapFromDataset(IModelDataMap modeloDataMap, DefaultTreeModel _metaS, String separador) {
        sourceModel = _metaS;
        this.mappingSchema.setMainModel(modeloDataMap, separador);
        this.mappingSchema.setModelMap(sourceModel, targetModel);
        this.mappingSchema.set3OntologyModel(evento, myPlaceHasCom, myPlaceHasItem, myComHasUser);
        this.mappingSchema.startMappingMode();
    }
}
